/**
 * @FileName: ProductController.java
 * @Author
 * @Description:
 * @Date 2016年5月27日 上午10:25:07
 * @CopyRight ZTE Corporation
 */
package cn.hpclub.server.controller.client;

import java.util.concurrent.ConcurrentHashMap;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.kit.StrKit;

import cn.hpclub.server.constant.ClientApiConstant;
import cn.hpclub.server.model.CmccCity;
import cn.hpclub.server.model.product.Product;
import cn.hpclub.server.restful.API;
import cn.hpclub.server.service.CmccService;
import cn.hpclub.server.service.CmccService.GetActivitiesExcettion;
import cn.hpclub.server.service.CmccService.ValidVerifyCodeException;
import cn.hpclub.server.service.TokenService;
import cn.hpclub.server.service.product.ProductBusinessService;

@API("/product")
public class ProductBusinessController extends BaseClientController<Product>{
    private static final Logger logger = LoggerFactory.getLogger(ProductBusinessController.class);

    /**
     * @Title: getActivities
     * @Description:终端销售时，获取合约的活动列表及详情
     */
    public void getActivities(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);

        String phoneNo = getPara("phoneno");// 办理号码
        String verifyCode = getPara("verifycode");// 验证码
        int errorType = getParaToInt("errortype", 1011);// 错误类型，默认传1011
        String loginno = getPara("loginno");

        try{
            ConcurrentHashMap<String, String> searchInfo = getSearchInfo();
            if((errorType == 1011 && StrKit.isBlank(verifyCode)) || StrKit.isBlank(phoneNo) || searchInfo == null){
                logger.error("*****getactivities params error!!! phoneno = " + phoneNo + ",,,verifycode = "
                        + verifyCode);
                jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.GETACTIVITIES_ERROR,
                                    ClientApiConstant.Msg.EMPTY);
                renderText(jo.toString());
                return;
            }

            // errorType为1011表示要走验证验证码的流程，即：第一次获取活动，或者之前获取活动时验证验证码不通过或者异常了
            // errorType为1012表示不走验证验证码的流程，即：之前获取活动时验证验证码通过了，但获取活动时异常了
            // 1、验证验证码
            if(errorType == 1011){
                String verifyCodeResult = "";
                try{
                    verifyCodeResult = CmccService.service.getValidVerifyCodeResult(phoneNo, verifyCode);
                    logger.debug("cmcc getValidVerifyCodeResult = " + verifyCodeResult);
                    if(StrKit.isBlank(verifyCodeResult)){
                        // 验证码校验异常，返回错误码：1011，错误信息：验证验证码失败
                        logger.error("cmcc server validRandPass Exception!!!");
                        throw new ValidVerifyCodeException("cmcc server validRandPass Exception!!!");
                    } else{
                        JSONObject o = new JSONObject(verifyCodeResult);
                        if(ClientApiConstant.CmccResultCode.SUCCESS_CODE
                                .equals(o.getString(ClientApiConstant.CmccKey.RES_CODE))){
                            // 验证码校验成功，则获取活动
                            jo = cmccGetActivities(searchInfo);
                        } else{
                            logger.error("cmcc server validRandPass error，code = "
                                    + o.getString(ClientApiConstant.CmccKey.RES_CODE));
                            // 验证码校验错误，原样返回错误信息，返回错误码：1011
                            throw new ValidVerifyCodeException("cmcc server validRandPass error，code = "
                                    + o.getString(ClientApiConstant.CmccKey.RES_CODE));
                        }
                    }
                }
                catch(ValidVerifyCodeException e){
                    logger.warn("dpr校验短信验证码失败，尝试rest校验");
                    verifyCodeResult = CmccService.service.getValidVerifyCodeResultForRest(phoneNo, verifyCode,
                                                                                           loginno);
                    logger.debug("cmcc getValidVerifyCodeResult = " + verifyCodeResult);
                    if(StrKit.isBlank(verifyCodeResult)){
                        // 验证码校验异常，返回错误码：1011，错误信息：验证验证码失败
                        logger.error("cmcc server validRandPass Exception!!!");
                        jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_VALID_RAND_PASS_EXCEPTION, "验证验证码失败",
                                            ClientApiConstant.Msg.EMPTY);
                    } else{
                        JSONObject o = new JSONObject(verifyCodeResult);
                        if(1000 == o.getInt("ResultCode")){
                            // 验证码校验成功，则获取活动
                            // jo = cmccGetActivities(mobile, modelCode, token);
                            jo = cmccGetActivities(searchInfo);
                        } else{
                            logger.error("cmcc server validRandPass error，code = " + o.getInt("ResultCode"));
                            // 验证码校验错误，原样返回错误信息，返回错误码：1011
                            jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_VALID_RAND_PASS_EXCEPTION,
                                                o.getString("Message"), ClientApiConstant.Msg.EMPTY);
                        }
                    }
                }
            } else{
                // 2、获取活动
                jo = cmccGetActivities(searchInfo);
                // 打桩方法
                // jo = cmccGetActivitiesTest(searchInfo, verifyCode);
            }
        }
        catch(ValidVerifyCodeException e){
            logger.error(e.toString());
            // 验证码校验异常，返回错误码：1011，错误信息：验证验证码失败
            jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_VALID_RAND_PASS_EXCEPTION, "验证验证码失败",
                                ClientApiConstant.Msg.EMPTY);
        }
        catch(GetActivitiesExcettion e){
            logger.error(e.toString());
            // cmcc获取活动异常，返回错误码：1012，错误信息：获取活动失败
            jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_GETACTIVITIES_EXCEPTION,
                                ClientApiConstant.Msg.GETACTIVITIES_EXCEPTION, ClientApiConstant.Msg.EMPTY);
        }
        catch(Exception e){
            logger.error("getactivities Exception!!! phone_no = " + phoneNo);
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
            e.printStackTrace();
        }
        finally{
            renderText(jo.toString());
        }

    }

    /**
     * @Title: cmccGetActivitiesTest
     * @Description:TODO
     * @param searchInfo
     * @param verifyCode
     * @return JSONObject
     */
    private JSONObject cmccGetActivitiesTest(ConcurrentHashMap<String, String> searchInfo, String verifyCode){
        JSONObject jo = new JSONObject();
        String result = "";
        // String result = CmccService.service.getActivities(searchInfo);
        // logger.debug("cmccGetActivities result = " + result);

        // 测试数据
        if("111111".equals(verifyCode)){
            // 合约机、裸机都有数据
            result = "{\"resCode\":\"0000000\",\"resMsg\":\"成功\",\"outData\":{\"type\":\"node\",\"RETURN_INFO\":[{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20010023\",\"RESOURCE_NAME\":\"OPPO-A33(二库)\",\"ACT_ID\":\"BS01\",\"ACT_NAME\":\"全省4季度岁末终端营销活动\",\"MEANS_ID\":\"BS010601\",\"MEANS_NAME\":\"全省二类库终端营销活动在网6月(收入)\",\"LOW_FEE\":\"38\",\"RESOURCE_MONTH\":\"6\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"1399\",\"GIVE_MONEY\":\"78\"},{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20010023\",\"RESOURCE_NAME\":\"OPPO-A33(二库)\",\"ACT_ID\":\"BS01\",\"ACT_NAME\":\"全省4季度岁末终端营销活动\",\"MEANS_ID\":\"BS010601\",\"MEANS_NAME\":\"全省二类库终端营销活动在网6月(收入)\",\"LOW_FEE\":\"58\",\"RESOURCE_MONTH\":\"6\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"1399\",\"GIVE_MONEY\":\"120\"},{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20009564\",\"RESOURCE_NAME\":\"FNNI-P8(裸)\",\"ACT_ID\":\"BZ01\",\"ACT_NAME\":\"全省4G资费终端合约活动\",\"MEANS_ID\":\"CZ010012\",\"MEANS_NAME\":\"全省4G资费终端合约活动低端（三库）(裸机)\",\"LOW_FEE\":\"0\",\"RESOURCE_MONTH\":\"0\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"0\",\"GIVE_MONEY\":\"0\"},{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20009564\",\"RESOURCE_NAME\":\"FNNI-P8(裸)\",\"ACT_ID\":\"BZ01\",\"ACT_NAME\":\"全省4G资费终端合约活动\",\"MEANS_ID\":\"CZ010015\",\"MEANS_NAME\":\"全省4G资费终端合约活动低端（三库）(裸机)\",\"LOW_FEE\":\"0\",\"RESOURCE_MONTH\":\"0\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"0\",\"GIVE_MONEY\":\"0\"}]},\"detailMsg\":\"成功\"}";
        } else if("222222".equals(verifyCode)){
            // 合约机无数据，裸机有数据
            result = "{\"resCode\":\"0000000\",\"resMsg\":\"成功\",\"outData\":{\"type\":\"node\",\"RETURN_INFO\":[{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20009564\",\"RESOURCE_NAME\":\"FNNI-P8(裸)\",\"ACT_ID\":\"BZ01\",\"ACT_NAME\":\"全省4G资费终端合约活动\",\"MEANS_ID\":\"CZ010012\",\"MEANS_NAME\":\"全省4G资费终端合约活动低端（三库）(裸机)\",\"LOW_FEE\":\"0\",\"RESOURCE_MONTH\":\"0\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"0\",\"GIVE_MONEY\":\"0\"},{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20009564\",\"RESOURCE_NAME\":\"FNNI-P8(裸)\",\"ACT_ID\":\"BZ01\",\"ACT_NAME\":\"全省4G资费终端合约活动\",\"MEANS_ID\":\"CZ010015\",\"MEANS_NAME\":\"全省4G资费终端合约活动低端（三库）(裸机)\",\"LOW_FEE\":\"0\",\"RESOURCE_MONTH\":\"0\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"0\",\"GIVE_MONEY\":\"0\"}]},\"detailMsg\":\"成功\"}";
        } else if("333333".equals(verifyCode)){
            // 合约机有数据，裸机无数据
            result = "{\"resCode\":\"0000000\",\"resMsg\":\"成功\",\"outData\":{\"type\":\"node\",\"RETURN_INFO\":[{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20010023\",\"RESOURCE_NAME\":\"OPPO-A33(二库)\",\"ACT_ID\":\"BS01\",\"ACT_NAME\":\"全省4季度岁末终端营销活动\",\"MEANS_ID\":\"BS010601\",\"MEANS_NAME\":\"全省二类库终端营销活动在网6月(收入)\",\"LOW_FEE\":\"38\",\"RESOURCE_MONTH\":\"6\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"1399\",\"GIVE_MONEY\":\"78\"},{\"type\":\"node\",\"BATCH_NO\":\"qwb000000000033\",\"RESOURCE_CODE\":\"20010023\",\"RESOURCE_NAME\":\"OPPO-A33(二库)\",\"ACT_ID\":\"BS01\",\"ACT_NAME\":\"全省4季度岁末终端营销活动\",\"MEANS_ID\":\"BS010601\",\"MEANS_NAME\":\"全省二类库终端营销活动在网6月(收入)\",\"LOW_FEE\":\"58\",\"RESOURCE_MONTH\":\"6\",\"PAY_MONEY\":\"0\",\"BUY_MONEY\":\"1399\",\"GIVE_MONEY\":\"120\"}]},\"detailMsg\":\"成功\"}";
        } else if("444444".equals(verifyCode)){
            // 合约机、裸机都无数据
            result = "{\"resCode\":\"0000000\",\"resMsg\":\"成功\",\"outData\":{\"type\":\"node\",\"RETURN_INFO\":[]},\"detailMsg\":\"成功\"}";
        }

        if(StrKit.isBlank(result)){
            // cmcc获取活动异常，返回错误码：1012，错误信息：获取活动失败
            jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_GETACTIVITIES_EXCEPTION,
                                ClientApiConstant.Msg.GETACTIVITIES_EXCEPTION, ClientApiConstant.Msg.EMPTY);
            logger.debug("to client data = " + jo.toString());
        } else{
            JSONObject o = new JSONObject(result);
            if(ClientApiConstant.CmccResultCode.SUCCESS_CODE.equals(o.getString(ClientApiConstant.CmccKey.RESCODE))){
                JSONObject activities = ProductBusinessService.service
                        .getActivities(o.getJSONObject(ClientApiConstant.CmccKey.OUTDATA));

                jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS,
                                    activities);
            } else{
                logger.error("cmcc server getActivities error，result = " + result);
                // cmcc获取活动错误，原样返回错误信息，返回错误码：1012
                jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_GETACTIVITIES_EXCEPTION,
                                    o.getString(ClientApiConstant.CmccKey.RESMSG), ClientApiConstant.Msg.EMPTY);

                logger.debug("to client data = " + jo.toString());
            }

        }

        return jo;
    }

    /**
     * @Title: cmccGetActivities
     * @Description:TODO
     * @param searchInfo
     * @return JSONObject
     */
    private JSONObject cmccGetActivities(ConcurrentHashMap<String, String> searchInfo)
            throws GetActivitiesExcettion, Exception{
        JSONObject jo = new JSONObject();
        // String result = CmccService.service.getActivities(mobile, modelCode,
        // token);
        String result = CmccService.service.getActivities(searchInfo);
        // logger.debug("cmccGetActivities result = " + result);

        if(StrKit.isBlank(result)){
            // cmcc获取活动异常，返回错误码：1012，错误信息：获取活动失败
            jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_GETACTIVITIES_EXCEPTION,
                                ClientApiConstant.Msg.GETACTIVITIES_EXCEPTION, ClientApiConstant.Msg.EMPTY);
            logger.debug("to client data = " + jo.toString());
        } else{
            JSONObject resObj = null;
            try{
                resObj = new JSONObject(result);
                JSONObject o = resObj.getJSONObject(ClientApiConstant.CmccKey.ROOT);
                if(ClientApiConstant.CmccResultCode.ESB_CODE_SUC
                        .equals(o.getString(ClientApiConstant.CmccKey.RETURN_CODE))){
                    JSONObject activities = ProductBusinessService.service
                            .getActivities(o.getJSONObject(ClientApiConstant.CmccKey.RETURN_INFO_LIST));

                    jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS,
                                        activities);
                } else{
                    logger.error("cmcc server getActivities error，result = " + result);
                    // cmcc获取活动错误，原样返回错误信息，返回错误码：1012
                    jo = setResponseObj(ClientApiConstant.ResultCode.CMCC_GETACTIVITIES_EXCEPTION,
                                        "错误码" + o.getString(ClientApiConstant.CmccKey.RETURN_CODE) + ":"
                                                + o.getString(ClientApiConstant.CmccKey.DETAIL_MSG),
                                        ClientApiConstant.Msg.EMPTY);

                    logger.debug("to client data = " + jo.toString());
                }
            }
            catch(JSONException ex){
                logger.error("result parse exception : " + result);

                if(null != resObj && resObj.has(ClientApiConstant.CmccKey.ROOT)
                        && resObj.getJSONObject(ClientApiConstant.CmccKey.ROOT)
                                .has(ClientApiConstant.CmccKey.RETURN_MSG)
                        && StrKit.notBlank(resObj.getJSONObject(ClientApiConstant.CmccKey.ROOT)
                                .getString(ClientApiConstant.CmccKey.RETURN_MSG))){
                    jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION,
                                        resObj.getJSONObject(ClientApiConstant.CmccKey.ROOT)
                                                .getString(ClientApiConstant.CmccKey.RETURN_MSG),
                                        ClientApiConstant.Msg.EMPTY);
                } else{
                    jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, result,
                                        ClientApiConstant.Msg.EMPTY);
                }

                ex.printStackTrace();
            }
        }

        return jo;
    }

    /**
     * @Title: getSearchInfo
     * @Description:TODO
     * @return ConcurrentHashMap<String,String>
     */
    private ConcurrentHashMap<String, String> getSearchInfo(){
        ConcurrentHashMap<String, String> mapData = null;
        // String phoneNo = "15982614178";// 办理号码
        // String resourceCode = "20010023";// SKU对应的机型编码
        // String loginNo = "hbj801";// 工号
        // String groupId = "1045365";// 工号对应的渠道编码
        // int regionId = 18;
        // int regionId3 = 0;

        int regionId3 = 0;
        String phoneNo = getPara("phoneno");// 办理号码
        String resourceCode = getPara("resourcecode");// SKU对应的机型编码
        String loginNo = getPara("loginno");// 工号
        String groupId = getPara("groupid");// 工号对应的渠道编码

        int regionId = getParaToInt("regionid", 0);// 地市编码，2位数的，需要根据该字段获取3位数的地市编码
        String token = getPara(ClientApiConstant.Key.TOKEN);

        if(StrKit.notBlank(phoneNo) && StrKit.notBlank(resourceCode) && StrKit.notBlank(loginNo)
                && StrKit.notBlank(groupId) && regionId != 0){
            mapData = new ConcurrentHashMap<String, String>();
            CmccCity city = CmccCity.dao.getRegionId3ByregionId(regionId);

            if(city != null){
                regionId3 = city.getInt(CmccCity.REGION_ID_3);
                // resource_code=20010023&region_id=118&phone_no=15982614178&login_no=hbj801&group_id=1045365
                mapData.put(ClientApiConstant.CmccKey.RESOURCE_CODE, resourceCode);
                mapData.put(ClientApiConstant.CmccKey.REGION_ID, String.valueOf(regionId3));
                mapData.put(ClientApiConstant.CmccKey.PHONE_NO_LOWER, phoneNo);
                mapData.put(ClientApiConstant.CmccKey.LOGIN_NO, loginNo);
                mapData.put(ClientApiConstant.CmccKey.GROUP_ID, groupId);
                mapData.put("TOKEN", token);

            } else{
                logger.error("*****getactivities get region_id_3 param error!!!");
            }

        } else{
            if(StrKit.notBlank(token)){
                // TODO 地市编码、工号、渠道编码没有，可以通过token取
                // Record memberInfo =
                // TokenService.service.getMemberOrgInfoByToken(token);
            }
            logger.error("*****getactivities params error!!! phoneno = " + phoneNo + ",,,resourcecode = " + resourceCode
                    + ",,,loginno = " + loginNo + ",,,groupid = " + groupId + ",,,regionid = " + regionId
                    + ",,,token = " + token);
        }

        return mapData;
    }

    /**
     * @Title: validate
     * @Description:终端销售时，校验串号 reso:IMEI号 batchno:为查询接口返回的BATCH_NO
     *                         groupid:工号对应的渠道编码 loginno:工号
     *                         optype:操作类型,合约机传4976，非合约机传4975
     */
    public void validate(){
        String resNo = getPara("resno");
        String batchNo = getPara("batchno");
        String groupId = getPara("groupid");
        String loginNo = getPara("loginno");
        String opType = getPara("optype");
        String token = getPara(ClientApiConstant.Key.TOKEN);
        String phoneNo = TokenService.service.getUsernameByToken(token);
        logger.debug("token=" + token);
        logger.debug("phoneNo=" + phoneNo);
        ProductBusinessService businessService = new ProductBusinessService();
        String reuslt = businessService.validate(batchNo, groupId, loginNo, resNo, opType, phoneNo, token);
        logger.debug("reuslt=" + reuslt);
        renderJson(reuslt);
    }

}
